package com.pearlsoft.webapp.core.dataset;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 * 
 * AbstractDataSet
 * 
 * @Creator haitingr
 * @Create-DateTime 2011-10-24
 */
public abstract class AbstractDataSet implements DataSet {

	protected String name;

	protected Map<String, Field> fields = new HashMap<String, Field>();

	protected List<DataSetFilter> filters = new ArrayList<DataSetFilter>();

	protected List<Record> records = new ArrayList<Record>();

	protected List<Condition> conditions = new ArrayList<Condition>();

	protected Iterator<Record> iterator = null;

	protected Record currentRecord = null;
	
	private int pageSize = Query.DEFAULT_PAGE_SIZE;

	private int totalCount;

	private int startIndex = 0;
	
	private boolean success = true;
	
	public AbstractDataSet(String name) {
		this.name = name;
	}

	public AbstractDataSet(String name, List<Field> fields) {
		this.name = name;
		for (Field f : fields) {
			this.fields.put(f.getName(), f);
		}
	}

	public AbstractDataSet(String name, List<Field> fields, List<DataSetFilter> filters) {
		this(name, fields);
		this.filters.addAll(filters);
	}

	public void addCondition(String name, Object value) throws DataSetFieldNotExistException {
		Condition condition = new Condition(name, value);
		this.conditions.add(condition);
	}

	public Map<String, Object> getConditions() {
		Map<String, Object> map = new HashMap<String, Object>();
		for (Condition condition : this.conditions) {
			map.put(condition.getFieldName(), condition.getValue());
		}
		return map;
	}

	public boolean next() {
		if (iterator == null) {
			if( this.records ==null){
				return false;
			}
			iterator = this.records.iterator();
		}
		if (iterator.hasNext()) {
			this.currentRecord = iterator.next();
			return true;
		} else {
			return false;
		}
	}

	public void first() {
		this.iterator = this.records.iterator();
		this.currentRecord = iterator.next();
	}

	public void last() {
		this.iterator = this.records.iterator();
		while (this.iterator.hasNext()) {
			this.currentRecord = this.iterator.next();
		}
	}

	public void reset() {
		this.iterator = null;
		this.currentRecord = null;
	}

	public boolean newRecord() {
		currentRecord = new Record() {
			protected Map<String, Object> values = new HashMap<String, Object>();

			public Object getValue(String name) {
				return this.values.get(name);
			}

			public void setValue(String name, Object value) {
				this.values.put(name, value);
			}

			public Map<String, Object> toMap() {
				return new HashMap<String, Object>(values);
			}

		};
		this.records.add(this.currentRecord);
		return true;
	}

	public int size() {
		return this.records.size();
	}

	public void setValue(String name, Object value) {
		Field field = this.getField(name);
		if (field == null) {
			// throw new DataSetFieldNotExistException("field[" + name +
			// "] not exist in dataset[" + this.getName() + "]");
		}
		this.currentRecord.setValue(name, value);
	}

	public Object getValue(String name) {
		Field field = this.getField(name);
		if (field == null) {
			// throw new DataSetFieldNotExistException("field[" + name +
			// "] not exist in dataset[" + this.getName() + "]");
		}
		return this.currentRecord.getValue(name);
	}

	public Field getField(String name) {
		return this.fields.get(name);
	}

	public String getName() {
		return this.name;
	}
	
	public int getPageSize() {
		return pageSize;
	}

	public void setPageSize(int pageSize) {
		this.pageSize = pageSize;
	}

	public int getTotalCount() {
		return totalCount;
	}

	public int getEndIndex() {
		int endIndex;
		if (totalCount % pageSize == 0) {
			endIndex = totalCount / pageSize - 1;
		} else {
			endIndex = (int) totalCount / pageSize;
		}
		if (endIndex < 0) {
			endIndex = 0;
		}
		return pageSize * endIndex;
	}

	public void setTotalCount(int totalCount) {
		if (totalCount > 0) {
			this.totalCount = totalCount;
			int count = totalCount / pageSize;
			if (totalCount % pageSize > 0) {
				count++;
			}
		} else {
			this.totalCount = 0;
		}
	}



	public int getStartIndex() {
		return startIndex;
	}

	public void setStartIndex(int startIndex) {
	    this.startIndex = startIndex;
	}

	public int getNextIndex() {
		int nextIndex = getStartIndex() + pageSize;
		if (nextIndex >= totalCount) {
			return getStartIndex();
		} else {
			return nextIndex;
		}
	}

	public int getPreviousIndex() {
		int previousIndex = getStartIndex() - pageSize;
		if (previousIndex < 0) {
			return 0;
		} else {
			return previousIndex;
		}
	}

	public int getPageIndex() {
		return this.getStartIndex() / this.pageSize + 1;
	}

	public int getPageCount() {
		return this.getEndIndex() / this.pageSize + 1;
	}
	
	public void setFields(List<Field> fields){
		for (Field f : fields) {
			this.fields.put(f.getName(), f);
		}
	}

	public boolean isSuccess() {
		return success;
	}

	public void setSuccess(boolean success) {
		this.success = success;
	}

	/**
	 * @return the records
	 */
	public List<Record> getRecords() {
		return records;
	}

	/**
	 * @param records the records to set
	 */
	public void setRecords(List<Record> records) {
		this.records = records;
	}

	public void addRecrod(Record record) {
		if( records == null ){
			records = new ArrayList<Record>(); 
		}
		currentRecord = record;
		records.add(record);
	}

	public Record getCurrentRecord() {
		return currentRecord;
	}


}
